package com.ms.orm.mapper;

import com.ms.orm.constants.Constants;

import java.util.Map;

/**
 * @author zdh
 * 动态sql中 <if test="age != null"> 内容解析，并根据传入的 Context (Map<String,Object>) 判断真假，
 *  目录之前表达式类型:
 *  name != null"
 *  age != ''
 *  name != null && name != ""
 *  name??
 *  age != null || age != null
 *  等
 */
public class ExpressionEvaluator {

    /**
     *
     * @param expression 表达式
     * @param params 参数对象（上下文环境对象）
     * @return
     */
    public static boolean evaluateExpression(String expression, Map<String, Object> params) {
        try {
            // 1、替换 '??' 逻辑为更简单的形式
            if (expression.contains("??")) {
                String property = expression.replace("??", "").trim();
                return isPropertyNonEmpty(params.get(property));
            }

            //2、分割表达式以处理 && 和 || 操作符
            String[] tokens = expression.split("(?=\\s*(&&|\\|\\|)\\s*)");
            //3、先对第一部分解析处理，即 && 或者 ||前面部分
            boolean result = evaluateToken(tokens[0].trim(), params);
            //4、然后变量后续部分，从第二个元素开始，因为第一个元素以及处理
            for (int i = 1; i < tokens.length; i++) {
                String token = tokens[i].trim();
                if (token.startsWith("&&")) {
                    //需要同时成立
                    result &= evaluateToken(token.substring(3).trim(), params);
                } else if (token.startsWith("||")) {
                    //只需要其中一个成立
                    result |= evaluateToken(token.substring(3).trim(), params);
                }
            }

            return result;
        } catch (Exception e) {
            throw new RuntimeException("Failed to evaluate expression: " + expression, e);
        }
    }

    /**
     *
     *
     * @param token
     * @param params
     * @return
     */
    private static boolean evaluateToken(String token, Map<String, Object> params) {
        // 处理简单条件
        //1、!=
        if (token.contains(Constants.NOT_EQUALS)) {
            String[] parts = token.split("\\s*!=\\s*");
            String key = parts[0].trim();
            String valueStr = parts[1].trim();

            if (Constants.NULL.equalsIgnoreCase(valueStr)) {
                //对 !="null"类型进行处理
                return params.get(key) != null;
            } else if (valueStr.isEmpty()) {
                return !isPropertyNonEmpty(params.get(key));
            } else {
                Object value = params.get(key);
                //值不为null 且 不等于 ""
                return value != null && !value.toString().equals(valueStr.replaceAll("^'|'$", ""));
            }
        } else if (token.contains(Constants.D_EQUALS)) {
            //2、处理==
            String[] parts = token.split("\\s*==\\s*");
            String key = parts[0].trim();
            String valueStr = parts[1].trim();

            if (Constants.NULL.equalsIgnoreCase(valueStr)) {
                return params.get(key) == null;
            } else if (valueStr.isEmpty()) {
                return isPropertyNonEmpty(params.get(key));
            } else {
                Object value = params.get(key);
                //等于 ""
                return value != null && value.toString().equals(valueStr.replaceAll("^'|'$", ""));
            }
        } else if (token.contains(Constants.QUESTION_MARK)) {
            //处理 ？号， 即是否非空
            String[] parts = token.split("\\s*\\?\\s*");
            String key = parts[0].trim();
            return isPropertyNonEmpty(params.get(key));
        } else {
            throw new IllegalArgumentException("Unsupported expression format: " + token);
        }
    }

    private static boolean isPropertyNonEmpty(Object value) {
        return value != null && !value.toString().isEmpty();
    }
}
